package com.benshou.bcss.common.trace;

import com.benshou.bcss.common.j17common.annotation.NotNull;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Optional;

/**
 * HTTP 请求过滤器： TraceId
 *
 * @author <a href="mailto:liuzhenbang@benshou.com">Liu Zhenbang</a>
 */
public class TraceIdFilter extends OncePerRequestFilter {

    /**
     * TraceId 的 Request Header 名称
     */
    public static final String HEADER_NAME_TRACE_ID = "X-Trace-Id";

    @Override
    protected void doFilterInternal(
            @NotNull HttpServletRequest request,
            @NotNull HttpServletResponse response,
            @NotNull FilterChain filterChain) throws ServletException, IOException {
        // 如传入 TraceId ，仍旧按原链路继续。否则生成新的 TraceId
        var traceIdOptional = Optional.ofNullable(request.getHeader(HEADER_NAME_TRACE_ID))
                .filter(traceId -> !traceId.isBlank());
        String traceId;
        if (traceIdOptional.isPresent()) {
            TraceIdContext.set(traceId = traceIdOptional.get());
        } else {
            traceId = TraceIdContext.getOrInitialize();
        }

        try {
            response.setHeader(HEADER_NAME_TRACE_ID, traceId);
            filterChain.doFilter(request, response);
        } finally {
            TraceIdContext.remove();
        }
    }
}
